
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class AESHelper {
    private final String CIPHERMODEPADDING = "AES/CBC/PKCS7Padding";

    private SecretKeySpec skforAES = null;

    private IvParameterSpec IV;

    public AESHelper(String secret) {
        int HASH_ITERATIONS = 10000;
        int KEY_LENGTH = 256;

        char[] secretChar = secret.toCharArray();
        byte[] salt = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD,
                0xE, 0xF };
        PBEKeySpec myKeyspec = new PBEKeySpec(secretChar, salt, HASH_ITERATIONS, KEY_LENGTH);

        Security.addProvider(new BouncyCastleProvider());
        SecretKey sk = null;
        SecretKeyFactory keyfactory = null;
        try {
            keyfactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            sk = keyfactory.generateSecret(myKeyspec);

        } catch (NoSuchAlgorithmException nsae) {
            nsae.printStackTrace();
        } catch (InvalidKeySpecException ikse) {
            ikse.printStackTrace();
        }

        if (sk!=null) {
            byte[] skAsByteArray = sk.getEncoded();
            skforAES = new SecretKeySpec(skAsByteArray, "AES");

            String iv = "justtesttesttest";
            IV = new IvParameterSpec(iv.getBytes());
        } else {
            System.out.println("AESHelper密钥初始化失败");
        }

    }

    public String AESEncrypt(String plainText) {
        byte[] result = null;
        String resultStr = null;
        try {
            result = plainText.getBytes("UTF8");
        } catch (Exception e) {
            System.out.println("AESHelper加密内容转码失败");
        }

        if (result != null) {
            byte[] ciphertext = encrypt(CIPHERMODEPADDING, skforAES, IV, result);
            resultStr = new String(Base64.encode(ciphertext));

        }
        return resultStr;
    }

    public String AESDecrypt(String plainText) {
        if (plainText == null) {
            return null;
        }
        byte[] s = Base64.decode(plainText);
        byte[] resultB = decrypt(CIPHERMODEPADDING, skforAES, IV, s);

        return new String(resultB);
    }

    private byte[] encrypt(String cmp, SecretKey sk, IvParameterSpec IV,
                           byte[] msg) {
        try {
            Cipher c = Cipher.getInstance(cmp);
            c.init(Cipher.ENCRYPT_MODE, sk, IV);
            return c.doFinal(msg);
        } catch (NoSuchAlgorithmException nsae) {
            nsae.printStackTrace();
        } catch (NoSuchPaddingException nspe) {
            nspe.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return new byte[1];
    }

    private byte[] decrypt(String cmp, SecretKey sk, IvParameterSpec IV,
                           byte[] ciphertext) {
        try {
            Cipher c = Cipher.getInstance(cmp);
            c.init(Cipher.DECRYPT_MODE, sk, IV);
            return c.doFinal(ciphertext);
        } catch (NoSuchAlgorithmException nsae) {
            nsae.printStackTrace();
        } catch (NoSuchPaddingException nspe) {
            nspe.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return new byte[1];
    }
}